/**
 * 基本工具、专业工具 15个
 * by ZL 2018/11/27 重构
 */
import zrender from "zrender";
import ajax from "./ajax";
import config from "./config";
import utils from "./utils";
import render from "./render";
import modal from "./overview/";
export default {
  // ==== 图层 ====
  renderLayer(xmlNode) {
    const show = utils.getAttribute(xmlNode, "show", "int");
    const layerId = utils.getAttribute(xmlNode, "id", "int");
    // const name = utils.getAttribute(xmlNode, 'name');
    // 添加一个layer属性，1背景层，2设备层
    const layer = new zrender.Group({ layer: layerId });
    if (show === 0) layer.hide();
    if (xmlNode.children && xmlNode.children.length) {
      for (let i = 0; i < xmlNode.children.length; i++) {
        render.renderElement(layer, xmlNode.children[i]);
      }
    }
    return layer;
  },
  renderLine(xmlNode) {
    return new zrender.Line({
      shape: {
        x1: utils.getAttribute(xmlNode, "x1", "float"),
        y1: utils.getAttribute(xmlNode, "y1", "float"),
        x2: utils.getAttribute(xmlNode, "x2", "float"),
        y2: utils.getAttribute(xmlNode, "y2", "float"),
      },
      style: {
        stroke:
          utils.getAttribute(xmlNode, "ls", "int") === 0
            ? null
            : utils.getAttribute(xmlNode, "lc", "rgb"),
        lineDash: utils.getLineStyle(xmlNode, "ls"),
        opacity: utils.getAttribute(xmlNode, "alpha", "alpha"),
        lineWidth: utils.getAttribute(xmlNode, "lw", "int"),
        strokeNoScale: true,
      },
    });
  },
  // ==== 新增母线 2018/10/17 ====
  renderBus(xmlNode) {
    const keyid = utils.getAttribute(xmlNode, "keyid", "int");
    // const attrid = utils.getAttribute(xmlNode, 'attrid', 'int');
    const Bus = new zrender.Line({
      shape: {
        x1: utils.getAttribute(xmlNode, "x1", "float"),
        y1: utils.getAttribute(xmlNode, "y1", "float"),
        x2: utils.getAttribute(xmlNode, "x2", "float"),
        y2: utils.getAttribute(xmlNode, "y2", "float"),
      },
      style: {
        stroke:
          utils.getAttribute(xmlNode, "ls", "int") === 0
            ? null
            : utils.getAttribute(xmlNode, "lc", "rgb"),
        lineDash: utils.getLineStyle(xmlNode, "ls"),
        opacity: utils.getAttribute(xmlNode, "alpha", "alpha"),
        lineWidth: utils.getAttribute(xmlNode, "lw", "int"),
        strokeNoScale: true,
      },
    });
    // 同样用dtextRect获取焦点
    Bus.on("click", () => {
      const bound = Bus.getBoundingRect();
      // const scale = Bus.scale[0];
      render.dtextRect.attr({
        shape: {
          x: utils.getAttribute(xmlNode, "x1", "float") - bound.height / 2,
          y: utils.getAttribute(xmlNode, "y1", "float") - bound.height / 2,
          width: bound.width,
          height: bound.height,
        },
      });
    });
    // 添加双击事件
    if (keyid) {
      Bus.on("dblclick", () => {
        modal.openCustomModal(keyid);
      });
    }
    return Bus;
  },
  // ==== 新增连接线 2018/10/17 ====
  renderConnectLine(xmlNode) {
    const keyid = utils.getAttribute(xmlNode, "keyid", "int");
    // const attrid = utils.getAttribute(xmlNode, 'attrid', 'int');
    const d = utils.getAttribute(xmlNode, "d");
    const points = d.split(" ");
    const str = "M" + points.join("L");
    const ConnectLine = zrender.path.createFromString(str, {
      style: {
        stroke:
          utils.getAttribute(xmlNode, "ls", "int") === 0
            ? null
            : utils.getAttribute(xmlNode, "lc", "rgb"),
        lineDash: utils.getLineStyle(xmlNode, "ls"),
        opacity: utils.getAttribute(xmlNode, "alpha", "alpha"),
        lineWidth: utils.getAttribute(xmlNode, "lw", "int"),
        strokeNoScale: true,
      },
    });
    // 添加双击事件
    if (keyid) {
      ConnectLine.on("dblclick", () => {
        modal.openCustomModal(keyid);
      });
    }
    return ConnectLine;
  },
  // ==== 普通文本 ====
  renderText(xmlNode) {
    // 对字体大小处理
    const ts = utils.getAttribute(xmlNode, "ts");
    const fs = utils.getAttribute(xmlNode, "fs", "int");
    const tfr = utils.getAttribute(xmlNode, "tfr", "tfr");
    let fontSize = fs;
    if (fontSize < 6 && tfr) {
      fontSize = 6;
      tfr.scale[0] = (tfr.scale[0] * fs) / fontSize;
      tfr.scale[1] = (tfr.scale[1] * fs) / fontSize;
    }
    const Text = new zrender.Text({
      z: 2, // 把文字图层上移，避免被覆盖
      style: {
        text: ts, // .replace(/^\s+|\s*$/g, '')
        textFill: utils.getAttribute(xmlNode, "lc", "rgb"),
        // fontFamily: utils.getAttribute(xmlNode, 'ff', ''),
        // fontSize: fontSize * 4 / 3,
        // zrender存在一个多加px的错误
        font: fontSize + "pt " + utils.getAttribute(xmlNode, "ff", ""),
        textPadding: fontSize > 20 ? [4, 0, 0, 0] : null,
        opacity: utils.getAttribute(xmlNode, "alpha", "alpha"),
      },
      position: [
        utils.getAttribute(xmlNode, "x", "float"),
        utils.getAttribute(xmlNode, "y", "float"),
      ],
      ...tfr,
    });
    // 处理带换行符的情况，用rich处理
    if (ts && ts.indexOf("\n") > -1) {
      const tss = ts.split("\n");
      for (let i = 0; i < tss.length; i++) {
        tss[i] = "{a|" + tss[i] + "}";
      }

      Text.attr("style", {
        text: tss.join("\n"),
        rich: {
          a: {
            textLineHeight: (fontSize * 4) / 3 + 1,
          },
        },
      });
    }
    return Text;
  },
  renderRect(xmlNode) {
    // 此处临时处理一些绘图背景问题
    let fill =
      utils.getAttribute(xmlNode, "fm", "int") === 0
        ? null
        : utils.getAttribute(xmlNode, "fc", "rgb");
    // if (fill === 'rgb(0,0,0)') {
    //   fill = null;
    // }
    const Rect = new zrender.Rect({
      shape: {
        x: utils.getAttribute(xmlNode, "x", "float"),
        y: utils.getAttribute(xmlNode, "y", "float"),
        width: utils.getAttribute(xmlNode, "w", "float"),
        height: utils.getAttribute(xmlNode, "h", "float"),
      },
      style: {
        fill: fill,
        stroke:
          utils.getAttribute(xmlNode, "ls", "int") === 0
            ? null
            : utils.getAttribute(xmlNode, "lc", "rgb"),
        lineDash: utils.getLineStyle(xmlNode, "ls"),
        opacity: utils.getAttribute(xmlNode, "alpha", "alpha"),
        lineWidth: utils.getAttribute(xmlNode, "lw", "int"),
        strokeNoScale: true,
      },
    });
    return Rect;
  },
  renderPolyline(xmlNode) {
    const d = utils.getAttribute(xmlNode, "d");
    const points = d.split(" ");
    points.forEach((entry, index) => {
      points[index] = entry.split(",");
    });
    return new zrender.Polyline({
      shape: {
        points,
      },
      style: {
        stroke:
          utils.getAttribute(xmlNode, "ls", "int") === 0
            ? null
            : utils.getAttribute(xmlNode, "lc", "rgb"),
        lineDash: utils.getLineStyle(xmlNode, "ls"),
        opacity: utils.getAttribute(xmlNode, "alpha", "alpha"),
        lineWidth: utils.getAttribute(xmlNode, "lw", "int"),
        strokeNoScale: true,
      },
    });
  },
  renderCircle(xmlNode) {
    return new zrender.Circle({
      shape: {
        cx: utils.getAttribute(xmlNode, "cx", "float"),
        cy: utils.getAttribute(xmlNode, "cy", "float"),
        r: utils.getAttribute(xmlNode, "r", "float"),
      },
      style: {
        stroke:
          utils.getAttribute(xmlNode, "ls", "int") === 0
            ? null
            : utils.getAttribute(xmlNode, "lc", "rgb"),
        lineDash: utils.getLineStyle(xmlNode, "ls"),
        opacity: utils.getAttribute(xmlNode, "alpha", "alpha"),
        lineWidth: utils.getAttribute(xmlNode, "lw", "int"),
        strokeNoScale: true,
      },
    });
  },
  renderEllipse(xmlNode) {
    return new zrender.Ellipse({
      shape: {
        cx: utils.getAttribute(xmlNode, "cx", "float"),
        cy: utils.getAttribute(xmlNode, "cy", "float"),
        rx: utils.getAttribute(xmlNode, "rx", "float"),
        ry: utils.getAttribute(xmlNode, "ry", "float"),
      },
      style: {
        fill:
          utils.getAttribute(xmlNode, "fm", "int") === 0
            ? null
            : utils.getAttribute(xmlNode, "fc", "rgb"),
        stroke:
          utils.getAttribute(xmlNode, "ls", "int") === 0
            ? null
            : utils.getAttribute(xmlNode, "lc", "rgb"),
        lineDash: utils.getLineStyle(xmlNode, "ls"),
        opacity: utils.getAttribute(xmlNode, "alpha", "alpha"),
        lineWidth: utils.getAttribute(xmlNode, "lw", "int"),
        strokeNoScale: true,
      },
    });
  },
  renderPolygon(xmlNode) {
    const d = utils.getAttribute(xmlNode, "d");
    const points = d.split(" ");
    points.forEach((entry, index) => {
      points[index] = entry.split(",");
    });
    return new zrender.Polygon({
      shape: {
        points,
      },
      style: {
        fill:
          utils.getAttribute(xmlNode, "fm", "int") === 0
            ? null
            : utils.getAttribute(xmlNode, "fc", "rgb"),
        stroke:
          utils.getAttribute(xmlNode, "ls", "int") === 0
            ? null
            : utils.getAttribute(xmlNode, "lc", "rgb"),
        lineDash: utils.getLineStyle(xmlNode, "ls"),
        opacity: utils.getAttribute(xmlNode, "alpha", "alpha"),
        lineWidth: utils.getAttribute(xmlNode, "lw", "int"),
        strokeNoScale: true,
      },
    });
  },
  renderImage(xmlNode, preUrl) {
    const image =
      config.base_url + preUrl + utils.getAttribute(xmlNode, "ahref");
    return new zrender.Image({
      style: {
        x: utils.getAttribute(xmlNode, "x", "float"),
        y: utils.getAttribute(xmlNode, "y", "float"),
        width: utils.getAttribute(xmlNode, "w", "float"),
        height: utils.getAttribute(xmlNode, "h", "float"),
        image: image,
      },
      origin: [
        utils.getAttribute(xmlNode, "x", "float") +
          utils.getAttribute(xmlNode, "w", "float") / 2,
        utils.getAttribute(xmlNode, "y", "float") +
          utils.getAttribute(xmlNode, "h", "float") / 2,
      ],
      ...utils.getAttribute(xmlNode, "tfr", "tfr"),
      keyid: utils.getAttribute(xmlNode, "keyid", "int"),
    });
  },
  renderEllipseArc(xmlNode) {
    const rx = utils.getAttribute(xmlNode, "rx", "float");
    const ry = utils.getAttribute(xmlNode, "ry", "float");
    const scaleX = rx > ry ? 1 : rx / ry;
    const scaleY = rx > ry ? ry / rx : 1;
    const EllipseArc = zrender.Path.extend({
      type: "EllipseArc",
      shape: {
        cx: utils.getAttribute(xmlNode, "cx", "float"),
        cy: utils.getAttribute(xmlNode, "cy", "float"),
        p1: utils.getAttribute(xmlNode, "p1", "point"),
        p2: utils.getAttribute(xmlNode, "p2", "point"),
        rx: utils.getAttribute(xmlNode, "rx", "float"),
        ry: utils.getAttribute(xmlNode, "ry", "float"),
        a1: utils.getAttribute(xmlNode, "a1", "float"),
        a2: utils.getAttribute(xmlNode, "a2", "float"),
        ArcShape: utils.getAttribute(xmlNode, "ArcShape", "int"),
      },
      buildPath: (path, shape) => {
        path.beginPath();
        path.moveTo(shape.p2.x, shape.p2.y);
        path.arc(
          shape.cx,
          shape.cy,
          shape.rx > shape.ry ? shape.rx : shape.ry,
          2 * Math.PI - (Math.PI / 180) * shape.a2,
          2 * Math.PI - (Math.PI / 180) * shape.a1
        );
        if (shape.ArcShape === 2) {
          path.closePath();
        }
      },
    });
    return new EllipseArc({
      style: {
        fill:
          utils.getAttribute(xmlNode, "fm", "int") === 0
            ? null
            : utils.getAttribute(xmlNode, "fc", "rgb"),
        stroke:
          utils.getAttribute(xmlNode, "ls", "int") === 0
            ? null
            : utils.getAttribute(xmlNode, "lc", "rgb"),
        lineDash: utils.getLineStyle(xmlNode, "ls"),
        opacity: utils.getAttribute(xmlNode, "alpha", "alpha"),
        lineWidth: utils.getAttribute(xmlNode, "lw", "int"),
        strokeNoScale: true,
      },
      origin: [
        utils.getAttribute(xmlNode, "cx", "float"),
        utils.getAttribute(xmlNode, "cy", "float"),
      ],
      scale: [scaleX, scaleY],
    });
  },
  // ==== 链接锚点 ====
  renderLinkArea(xmlNode) {
    const cmd = utils.getAttribute(xmlNode, "cmd", "int");
    const p = utils.getAttribute(xmlNode, "p");
    const area = new zrender.Rect({
      z: 5, // 这里把链接图层上移，避免文字覆盖链接图层问题 2018/9/18
      shape: {
        x: utils.getAttribute(xmlNode, "x", "float"),
        y: utils.getAttribute(xmlNode, "y", "float"),
        width: utils.getAttribute(xmlNode, "w", "float"),
        height: utils.getAttribute(xmlNode, "h", "float"),
      },
      style: {
        fill: "#fff",
        opacity: 0,
      },
    });
    // 切换图id，todo：添加一个箭头按钮
    // cmd为1时，打开图，p为图id
    // cmd为4时，打开程序，p为string
    if (cmd === 1 && p) {
      area.on("click", () => {
        // 禁止掉最上层的目录图等
        // if (p === '100104') return;
        if (config.forbidList.indexOf(parseInt(p)) > -1) return;
        // 缓存上一级的picId，返回按钮
        const index = zrender.util.indexOf(render.cachePicId, render.picId);
        if (index > -1) {
          render.cachePicId.splice(index, 1);
        }
        render.cachePicId.push(render.picId);

        render.picId = parseInt(p);
        render.getRenderXml();
      });
    }
    if (cmd === 4 && p) {
      // 添加事件获取焦点
      area.on("mouseover", () => {
        area.attr({
          style: {
            opacity: 0.3,
          },
        });
      });
      area.on("mouseout", () => {
        area.attr({
          style: {
            opacity: 0,
          },
        });
      });
      // 调压分析，其他脚本暂不考虑
      const objMatch = /obj.initR\((\d+)\)/.exec(p);
      if (objMatch && objMatch.length) {
        area.on("dblclick", () => {
          modal.openTiaoyaModal(objMatch[1]);
        });
      }
    }
    return area;
  },
  // ==== 动态文本 ====
  renderDText(xmlNode) {
    const keyid = utils.getAttribute(xmlNode, "keyid", "int");
    const attrid = utils.getAttribute(xmlNode, "attrid", "int");
    // 这里增加了遥测图元属性 2018/10/9 by ZL
    const total = utils.getAttribute(xmlNode, "total", "int"); // 数值总位数
    const decimal = utils.getAttribute(xmlNode, "decimal", "int"); // 小数位数
    const prefix = utils.getAttribute(xmlNode, "prefix"); // 前缀
    const suffix = utils.getAttribute(xmlNode, "suffix"); // 后缀

    const DText = new zrender.Text({
      z: 2, // 把文字图层上移，避免被覆盖
      style: {
        text: "--.--",
        textFill: utils.getAttribute(xmlNode, "lc", "rgb"),
        // fontFamily: utils.getAttribute(xmlNode, 'ff', ''),
        // fontSize: utils.getAttribute(xmlNode, 'fs', 'int') * 4 / 3,
        font:
          utils.getAttribute(xmlNode, "fs", "int") +
          "pt " +
          utils.getAttribute(xmlNode, "ff", ""),
        opacity: 1,
      },
      position: [
        utils.getAttribute(xmlNode, "x", "float"),
        utils.getAttribute(xmlNode, "y", "float"),
      ],
      ...utils.getAttribute(xmlNode, "tfr", "tfr"),
    });
    // 添加单击事件，聚焦
    // DText.on('click', () => {
    //   const bound = DText.getBoundingRect();
    //   const scale = DText.scale[0];
    //   render.dtextRect.attr({
    //     shape: {
    //       x: utils.getAttribute(xmlNode, 'x', 'float') - 2,
    //       y: utils.getAttribute(xmlNode, 'y', 'float') - 3,
    //       width: bound.width * scale + 4,
    //       height: bound.height * scale + 2
    //     }
    //   });
    // });
    // 添加双击事件
    // DText.on('dblclick', () => {
    //   if (keyid) {
    //     modal.openCustomModal(keyid);
    //   }
    // });
    // 添加到节点缓存
    if (keyid && attrid) {
      render.cacheElement.push({
        keyid,
        attrid,
        element: DText,
        type: "DText",
        extra: [total, decimal, prefix, suffix],
      });
    }
    return DText;
  },
  // ==== 图元 ====
  renderStatus(xmlNode) {
    const devref = utils.getAttribute(xmlNode, "devref");
    const keyid = utils.getAttribute(xmlNode, "keyid", "int");
    const attrid = utils.getAttribute(xmlNode, "attrid", "int");
    const filename = devref.split(":")[0];
    const metaId = devref.split(":")[1];
    const status = new zrender.Group({
      position: [
        utils.getAttribute(xmlNode, "x", "float"),
        utils.getAttribute(xmlNode, "y", "float"),
      ],
      ...utils.getAttribute(xmlNode, "tfr", "tfr"),
    });
    // 通过立即执行函数去渲染图元元素
    (async () => {
      try {
        const metaXML = await ajax.GetMetaGXml(filename);
        const xmlDoc = metaXML.data.documentElement;
        const statusDoc = xmlDoc.getElementsByTagName("Status");
        // 处理ie兼容性问题 2018/5/22
        if (typeof xmlDoc.children === "undefined") {
          render.getXMLChildren(xmlDoc);
        }
        for (let i = 0; i < statusDoc.length; i++) {
          const id = utils.getAttribute(statusDoc[i], "id");
          // const stateNum = utils.getAttribute(statusDoc[i], 'state');
          // 设备附加状态处理
          if (statusDoc[i].children.length && id && id === metaId) {
            for (let k = 0; k < statusDoc[i].children.length; k++) {
              render.renderElement(status, statusDoc[i].children[k]);
            }
          }
        }
        // 计算缩放旋转的中心原点
        const statusBound = status.getBoundingRect();
        status.attr({
          origin: [
            statusBound.x + statusBound.width / 2,
            statusBound.y + statusBound.height / 2,
          ],
        });

        // 添加一个rect
        //  const statusRect = new zrender.Rect({
        //   shape: {
        //     r: 4,
        //     width: statusBound.width ,
        //     height: statusBound.height
        //   },
        //   style: {
        //     // text: metaId, // ====非调试模式注释掉====
        //     fill: '#fff',
        //     opacity: 1
        //   },
        //   position: [
        //     statusBound.x,
        //     statusBound.y
        //   ],
        // });
        // status.add(statusRect);
        // 在status上添加双击事件
        // status.on('dblclick', () => {
        //   console.log(keyid + '--' + attrid);
        //   if (keyid) {
        //     // modal.openCustomModal(keyid);
        //   }
        // });
        // 在status上添加点击事件
        status.on("mouseover", async event => {
          if (keyid) {
            // console.log(keyid + "--" + attrid, event);
            modal.openCustomModal(keyid, attrid, event);
          }
        });

        status.on("mouseout", () => {
          console.log("mouseout离开了");
          modal.destoryModal();
        });

        // 所有图元默认状态都是0 by ZL 2018/9/29
        render.refreshStatus(status, "0");
      } catch (e) {
        // 中断请求
      }
    })();
    // 添加到节点缓存
    if (keyid && attrid) {
      const cacheStatus = {
        keyid,
        attrid,
        metaId,
        element: status,
        type: "Status",
      };
      // 1344 添加旋转动画效果
      if (metaId === "1344") {
        cacheStatus.animate = status
          .animate("", true)
          .when(2000, { rotation: Math.PI / 2 });
      }
      // 1288 光子牌的眨眼动画
      if (metaId === "1288") {
        setTimeout(() => {
          let child = null;
          if (status.childCount()) {
            child = status.childAt(0);

            if (child.childCount()) {
              child = child.childAt(1);
            }
          }
          if (child) {
            cacheStatus.animate = status
              .childAt(0)
              .childAt(1)
              .animate("style", true)
              .when(800, { fill: "#000" });
          }
        }, 300);
      }
      // 1298 设备状态的眨眼动画
      if (metaId === "1298") {
        setTimeout(() => {
          let child = null;
          if (status.childCount()) {
            child = status.childAt(0);

            if (child.childCount()) {
              child.childAt(0) && child.childAt(0).attr("z", 1); // 防止被覆盖
              child.childAt(1) && child.childAt(1).attr("z", 1);
              child = child.childAt(0);
            }
          }
          if (child) {
            cacheStatus.animate = status
              .childAt(0)
              .childAt(0)
              .animate("style", true)
              .when(800, { fill: "#22b14c", stroke: "#22b14c" });
          }
        }, 300);
      }
      render.cacheElement.push(cacheStatus);
    }
    // console.log(status);
    return status;
  },
};
